package com.ideal.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ideal.dto.config.req.FileContentModReqDto;
import com.ideal.dto.config.req.VersionPageReqDto;
import com.ideal.dto.config.res.VersionCompareDataRsqDto;
import com.ideal.dto.config.res.VersionPageRspDto;
import com.ideal.dto.config.res.execl.ExeclData;
import com.ideal.enums.FileTypeEnum;
import com.ideal.mapper.ConfigVersionMapper;
import com.ideal.model.ConfigVersion;
import com.ideal.service.IConfigVersionService;
import com.ideal.util.file.ExeclUtil;
import com.ideal.util.file.IniUtil;
import com.ideal.util.file.PropertiesUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 配置版本 Service业务层处理
 *
 * @author songfz
 * @date 2022-07-13
 */
@Service
public class ConfigVersionServiceImpl implements IConfigVersionService
{
    @Autowired
    private ConfigVersionMapper configVersionMapper;

    /**
     * 查询配置版本
     *
     * @param id 配置版本 主键
     * @return 配置版本
     */
    @Override
    public ConfigVersion selectConfigVersionById(Long id)
    {
        return configVersionMapper.selectConfigVersionById(id);
    }

    /**
     * 查询配置版本 列表
     *
     * @param configVersion 配置版本
     * @return 配置版本
     */
    @Override
    public List<ConfigVersion> selectConfigVersionList(ConfigVersion configVersion)
    {
        return configVersionMapper.selectConfigVersionList(configVersion);
    }

    /**
     * 新增配置版本
     *
     * @param configVersion 配置版本
     * @return 结果
     */
    @Override
    public int insertConfigVersion(ConfigVersion configVersion)
    {
        return configVersionMapper.insertConfigVersion(configVersion);
    }

    /**
     * 修改配置版本
     *
     * @param configVersion 配置版本
     * @return 结果
     */
    @Override
    public int updateConfigVersion(ConfigVersion configVersion)
    {
        return configVersionMapper.updateConfigVersion(configVersion);
    }

    /**
     * 批量删除配置版本
     *
     * @param ids 需要删除的配置版本 主键
     * @return 结果
     */
    @Override
    public int deleteConfigVersionByIds(Long[] ids)
    {
        return configVersionMapper.deleteConfigVersionByIds(ids);
    }

    /**
     * 删除配置版本 信息
     *
     * @param id 配置版本 主键
     * @return 结果
     */
    @Override
    public int deleteConfigVersionById(Long id)
    {
        return configVersionMapper.deleteConfigVersionById(id);
    }

    @Override
    public PageInfo versionPage(VersionPageReqDto pageReqDto) {

        PageHelper.startPage(pageReqDto.getPageNum(), pageReqDto.getPageSize());
        List<VersionPageRspDto> rspList = this.configVersionMapper.findByPageParams(pageReqDto);
        PageInfo<VersionPageRspDto> info = new PageInfo<>(rspList);
        return info;
    }

    /**
     * 获取当前使用的版本文件
     *
     * @param roleGroup
     * @param configId
     * @return
     */
    @Override
    public ConfigVersion findUseVersionByConfigId(String roleGroup, Long configId) {

        return this.configVersionMapper.findUseVersionByConfigId(roleGroup,configId);
    }

    @Override
    public void downloadByConfigId(HttpServletResponse response, Long versionId) {
        ConfigVersion configVersion = configVersionMapper.selectConfigVersionById(versionId);
        String path = configVersion.getFileUrl();
        try {
            // path是指欲下载的文件的路径。
            File file = new File(path);
            // 取得文件名。
            String filename = file.getName();
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
            response.addHeader("Content-Length", "" + file.length());
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            // 循环取出流中的数据
            try (InputStream fis = new BufferedInputStream(new FileInputStream(path))) {
                byte[] b = new byte[1024];
                int len;
                while ((len = fis.read(b)) > 0) {
                    response.getOutputStream().write(b, 0, len);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            toClient.flush();
            toClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void updateContentByVersion(FileContentModReqDto fileContentModReqDto) {
        this.configVersionMapper.updateContentByVersion(fileContentModReqDto);
    }

    @Override
    public ConfigVersion findByVersion(String version) {
        return this.configVersionMapper.findByVersion(version);
    }

    /**
     * 版本比对数据
     * @param versionIds
     * @return
     */
    @Override
    public List<VersionCompareDataRsqDto> compareData(Long[] versionIds) {

        //  获取要对比的数据
        final List<Map<String, String>> data = this.configVersionMapper.compareData(versionIds);

        Boolean isExecl = false;
        final List<VersionCompareDataRsqDto> list = new ArrayList<>();
        for (Map<String, String> datum : data) {
            final VersionCompareDataRsqDto result = new VersionCompareDataRsqDto();
            ExeclData execlData = null;
            List<String> contents = new ArrayList<>();

            final String fileUrl = datum.get("fileUrl");
            final String content = datum.get("content");

            isExecl = isExecl || FileTypeEnum.EXECL.getSubfix().equalsIgnoreCase(fileUrl.substring(fileUrl.lastIndexOf(".") + 1));

            String suffix = fileUrl.substring(fileUrl.lastIndexOf(".") + 1);

            if (FileTypeEnum.EXECL.getSubfix().equalsIgnoreCase(suffix)) {

                execlData = ExeclUtil.toConvert(ExeclUtil.strToJson(content));

            } else if (FileTypeEnum.INI.getSubfix().equals(suffix)) {

                contents.add(IniUtil.parse(content));
            } else if (FileTypeEnum.PROPERTIES.getSubfix().equals(suffix)) {
                contents.add(PropertiesUtil.parse(content));
            } else {
                //TODO
                return null;
            }
            result.setIsExecl(isExecl);
            result.setExeclData(execlData);
            result.setTextContent(contents);
            list.add(result);
        }

        return list;
    }

    /**
     * 获取当前配置所有启用的配置文件内容集合
     * @param configId
     * @return
     */
    @Override
    public List<ConfigVersion> findByConfigIdAndUserStatus(Long configId) {
        return this.configVersionMapper.findAllUseVersionByConfigId(configId);
    }

}
